package com.googlecode.javatools.classparser.impl;

import java.io.DataInput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.googlecode.javatools.classparser.AccessFlagParser;
import com.googlecode.javatools.classparser.AttributeInfoParser;
import com.googlecode.javatools.classparser.FieldInfoParser;
import com.googlecode.javatools.classparser.TypesInfoParser;
import com.googlecode.javatools.classparser.types.AttributeInfo;
import com.googlecode.javatools.classparser.types.ConstantEntry;
import com.googlecode.javatools.classparser.types.ConstantPool;
import com.googlecode.javatools.classparser.types.FieldInfo;
import com.googlecode.javatools.classparser.types.impl.FieldInfoImpl;

public class FieldInfoParserImpl implements FieldInfoParser
{
	public Collection<FieldInfo> parse(final DataInput in, final AccessFlagParser accessFlagParser,
			final AttributeInfoParser attributeInfoParser, final TypesInfoParser typesInfoParser,
			final ConstantPool constantPool) throws IOException
	{
		final int fieldsCount = in.readUnsignedShort();
		final List<FieldInfo> fields = new ArrayList<FieldInfo>(fieldsCount);

		for (int i = 0; i < fieldsCount; i++)
		{
			final int accessFlag = in.readUnsignedShort();
			final boolean isAbstract = accessFlagParser.isAbstract(accessFlag);
			final boolean isPublic = accessFlagParser.isPublic(accessFlag);

			final int nameIndex = in.readUnsignedShort();
			final ConstantEntry entry = constantPool.entryAt(nameIndex);
			final String fieldName = entry.toUTF8();

			final int descriptorIndex = in.readUnsignedShort();
			final ConstantEntry descriptorEntry = constantPool.entryAt(descriptorIndex);
			final String descriptor = descriptorEntry.toUTF8();

			final Collection<AttributeInfo> attributes = attributeInfoParser.parse(in, constantPool);

			final Collection<String> type = typesInfoParser.parse(descriptor);

			final FieldInfo field = new FieldInfoImpl(isAbstract, isPublic, fieldName, type);

			fields.add(field);
		}

		return fields;
	}
}
